package cc.cocosky.imclient;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;

public class SocketInvoker {
	
	private Socket socket;
	private OnReceiveHandler onReceiveHandler;
	
	public void connect(String host, int port) throws IOException {
		connect(new InetSocketAddress(host, port));
	}
	
	public void connect(SocketAddress address) throws IOException {
		socket = new Socket();
		socket.setTcpNoDelay(true);
		socket.setKeepAlive(true);
		socket.connect(address);
		new ReadThread(socket, onReceiveHandler).start();
	}
	
	public void disconnect() throws IOException {
		socket.close();
	}

	public void send(byte[] data) throws IOException {
		OutputStream out = socket.getOutputStream();
		ByteUtil.writeLength(out, data.length);
		ByteUtil.writeData(out, data);
		out.flush();
	}
	
	public void setOnReceiveHandler(OnReceiveHandler onReceiveHandler) {
		this.onReceiveHandler = onReceiveHandler;
	}
	
	static class ReadThread extends Thread {
		
		private Socket socket;
		private OnReceiveHandler onReceiveHandler;
		
		public ReadThread(Socket socket, OnReceiveHandler onReceiveHandler) {
			this.socket = socket;
			this.onReceiveHandler = onReceiveHandler;
		}
		
		private void receive() throws IOException {
			while(true){
				InputStream in = socket.getInputStream();
				int length = ByteUtil.readLength(in);
				if(length > 0) {
					byte[] data = ByteUtil.readData(in, length);
					if(onReceiveHandler != null) {						
						onReceiveHandler.onReceive(data);
					}
				}
			}
		}
		
		@Override
		public void run() {
			try {
				receive();
			} catch (IOException e) {
				System.err.println(e.getMessage());
			}
		}
	}
	
}
